using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;

namespace ZSW.Framework
{
    public class ZSWF_ObjectPool<T> : ZSWF_InitMonoBehaviour where T : Component
    {
        [Header("生成元素"), SerializeField] protected T m_element;

        [Header("元素父物体"), SerializeField] protected Transform m_elementParent;

        protected ObjectPool<T> m_elementPool;

        protected virtual int m_maxCount { get; set; } = 100;

        protected List<T> m_elementList = new List<T>();

        public override void Init()
        {
            m_elementPool = new ObjectPool<T>(OnCreate, OnGet, OnRelease, OnDestroyElement, false, 10, m_maxCount);
            base.Init();
        }

        public virtual T Get()
        {
            return m_elementPool.Get();
        }
        
        public virtual void Clear()
        {
            m_elementPool.Dispose();
            m_elementPool.Clear();
        }

        public virtual void Release(T element)
        {
            element.transform.parent = m_elementParent;
            m_elementPool.Release(element);
        }

        public virtual void ReleaseAllElement()
        {
            for (int i = m_elementList.Count - 1; i >= 0; i--)
            {
                T element = m_elementList[i];
                Release(element);
            }
        }

        /// <summary>
        /// 生成时
        /// </summary>
        /// <returns></returns>
        protected virtual T OnCreate()
        {
            return Instantiate(m_element, m_elementParent);
        }

        /// <summary>
        /// 获取时
        /// </summary>
        /// <param name="cement"></param>
        protected virtual void OnGet(T element)
        {
            m_elementList.Add(element);
            element.gameObject.SetActive(true);
        }

        /// <summary>
        /// 释放时
        /// </summary>
        /// <param name="cement"></param>
        protected virtual void OnRelease(T element)
        {
            m_elementList.Remove(element);
            element.gameObject.SetActive(false);
        }

        /// <summary>
        /// 删除时
        /// </summary>
        /// <param name="cement"></param>
        protected virtual void OnDestroyElement(T element)
        {
            Destroy(element.gameObject);
        }
    }

}